<?php

namespace app\api\model;

use app\api\service\Bank;
use think\Cache;
use app\common\library\wechat\WxUser;
use app\common\exception\BaseException;
use app\common\model\User as UserModel;
use app\api\model\dealer\Referee as RefereeModel;
use app\api\model\dealer\Setting as DealerSettingModel;
use app\common\model\Region;

/**
 * 用户模型类
 * Class User
 * @package app\api\model
 */
class User extends UserModel
{
    private $token;

    /**
     * 隐藏字段
     * @var array
     */
    protected $hidden = [
        'open_id',
        'is_delete',
        'wxapp_id',
        'create_time',
        'update_time'
    ];

    /**
     * 获取用户信息
     * @param $token
     * @return null|static
     * @throws \think\exception\DbException
     */
    public static function getUser($token)
    {
        $userId = Cache::get($token)['user_id'];
        return self::detail(['user_id' => $userId], ['address', 'addressDefault', 'grade']);
    }

    /**
     * 用户登录
     * @param array $post
     * @return string
     * @throws BaseException
     * @throws \think\Exception
     * @throws \think\exception\DbException
     */
//    public function login($post)
//    {
//        // 微信登录 获取session_key
//        $session = $this->wxlogin($post['code']);
//        // 自动注册用户
//        $referee_id = isset($post['referee_id']) ? $post['referee_id'] : null;
//        $userInfo = json_decode(htmlspecialchars_decode($post['user_info']), true);
//        $user_id = $this->register($session['openid'], $userInfo, $referee_id);
//        // 生成token (session3rd)
//        $this->token = $this->token($session['openid']);
//        // 记录缓存, 7天
//        Cache::set($this->token, $session, 86400 * 7);
//        return $user_id;
//    }
    public function login($post)
    {
        // 正确则 将用户信息存入 $userInfo
        $userInfo = $this->checklogin($post['mobile'],$post['password']);
        if(!$userInfo){
            return false;
        }
        // 生成token (session3rd)
        $this->token = $this->token($post['mobile']);
        // 记录缓存, 7天
        Cache::set($this->token,$userInfo, 86400 * 7);
        $user_id = $userInfo['user_id'];
        return $user_id;
    }
    /**
     * 判断用户名密码是否正确
     * @param  string $mobile
     * @param  string $password
     * @return bool
     * @throws BaseException
     * @throws \think\Exception
     * @throws \think\exception\DbException
     */
    public function checklogin($mobile,$password){
        $where = ['mobile'=>$mobile,'password'=>$password];
        // success
        $user = self::detail($where);

        return $user?$user:false;
    }
    /**
     * 获取token
     * @return mixed
     */
    public function getToken()
    {
        return $this->token;
    }

    /**
     * 微信登录
     * @param $code
     * @return array|mixed
     * @throws BaseException
     * @throws \think\exception\DbException
     */
    private function wxlogin($code)
    {
        // 获取当前小程序信息
        $wxConfig = Wxapp::getWxappCache();
        // 验证appid和appsecret是否填写
        if (empty($wxConfig['app_id']) || empty($wxConfig['app_secret'])) {
            throw new BaseException(['msg' => '请到 [后台-小程序设置] 填写appid 和 appsecret']);
        }
        // 微信登录 (获取session_key)
        $WxUser = new WxUser($wxConfig['app_id'], $wxConfig['app_secret']);
        if (!$session = $WxUser->sessionKey($code)) {
            throw new BaseException(['msg' => $WxUser->getError()]);
        }
        return $session;
    }

    /**
     * 生成用户认证的token
     * @param $openid
     * @return string
     */
    private function token($openid)
    {
        $wxapp_id = self::$wxapp_id;
        // 生成一个不会重复的随机字符串
        $guid = \getGuidV4();
        // 当前时间戳 (精确到毫秒)
        $timeStamp = microtime(true);
        // 自定义一个盐
        $salt = 'token_salt';
        return md5("{$wxapp_id}_{$timeStamp}_{$openid}_{$guid}_{$salt}");
    }

    /**
     * 自动注册用户
     * @param $open_id
     * @param $data
     * @param int $referee_id
     * @return mixed
     * @throws \Exception
     * @throws \think\exception\DbException
     */
    public function register($data, $referee_id = null)
    {
        if(!isset($data['mobile'])){
            throw new BaseException(['code'=>10000,'msg' => '手机号缺失','data'=>1]);
            return false;
        }
        // 查询用户是否已存在
        $user = self::detail(['mobile' => $data['mobile']]);
        if($user){
            throw new BaseException(['code'=>10001,'msg' => '该手机号已被占用','data'=>1]);
            return false;
        }
        if(!isset($data['idno'])){
            throw new BaseException(['code'=>10002,'msg' => '请传入身份证号','data'=>1]);
            return false;
        }
        if(!isset($data['region_id'])){
            throw new BaseException(['code'=>10002,'msg' => '请传入所在地','data'=>1]);
            return false;
        }
        if(!isset($data['detail'])){
            throw new BaseException(['code'=>10002,'msg' => '请传入详细地址','data'=>1]);
            return false;
        }
//        if(array_key_exists('vcode',$data)){
//            $cache_code = Cache::get('reg'.$data['mobile']);
//            if(isset($data['vcode'])&&!empty($cache_code)){
//                if($cache_code!=$data['vcode']){
//                    throw new BaseException(['msg' => '验证码错误','code'=>10005]);
//                }
//            }else{
//                throw new BaseException(['msg' => '验证码不能为空','code'=>10006]);
//            }
//        }else{
//            throw new BaseException(['msg' => '验证码参数丢失','code'=>10007]);
//        }
        // 查询用户是否已存在
        $model = $user ?: $this;
        $data['nickName'] = $data['name'];//preg_replace('/[\xf0-\xf7].{3}/', '', '用户'.rand(100000,999999));
        $this->startTrans();
        try {
            $data['region'] = isset($data['region_id'])?Region::getMergerName($data['region_id']):'中国,河北省,石家庄市,长安区';
            $region = explode(',', $data['region']);
            $province_id = Region::getIdByName($region[1], 1);
            $data['province'] = $region[1];
            $city_id = Region::getIdByName($region[2], 2, $province_id);
            $data['city'] = $region[2];
            $region_id = Region::getIdByName($region[3], 3, $city_id);
            $data['area'] = $region[3];
            $data['wxapp_id'] = self::$wxapp_id;
            $data['level_id'] = $referee_id > 0?$referee_id:0;
            $data['level_money'] = 0;

            // 保存/更新用户记录
            if (!$model->allowField(true)->save($data)) {
                throw new BaseException(['code'=>10002,'msg' => '用户注册失败-用户新建失败','data'=>null]);
            }
            // 记录推荐人关系
            if (!$user && $referee_id > 0) {
                RefereeModel::createRelation($model['user_id'], $referee_id);
            }
            // 新增联系人地址
            $uaddress = new UserAddress;
            $uaddress->allowField(true)->save([
                'name' => $data['name'],
                'phone' => $data['mobile'],
                'province_id' => $province_id,
                'city_id' => $city_id,
                'region_id' => $region_id,
                'detail' => isset($data['detail'])?$data['detail']:explode(" ",$data['region']),
                'district' => ($region_id === 0 && !empty($region[2])) ? $region[2] : '',
                'user_id' => $model['user_id'],
                'wxapp_id' => self::$wxapp_id
            ]);
            // 设为默认收货地址
            $model->allowField(true)->save(['address_id' => $uaddress['address_id']]);
            $bank = new Bank();
            $data['user_id'] = $model['user_id'];
            $bank->register($data);
            $this->commit();
        } catch (\Exception $e) {
            $this->rollback();
            throw new BaseException(['msg' => $e->getMessage()]);
        }
        $data['user_id'] = $model['user_id'];
        $data['address'] = $data['detail'];
        return $data;
    }

    /**
     * 编辑用户信息
     * @param $data
     * @return bool
     * @throws \think\exception\DbException
     */
    public function edit($data)
    {
        $token = $data['token'];
        $user_id = Cache::get($token)['user_id'];
        $user = self::detail(['user_id' => $user_id]);
        return $user->allowField(true)->save($data) !== false;
    }

    /**
     * 短信重置密码
     * @param $data
     * @return bool
     * @throws BaseException
     * @throws \think\exception\DbException
     */
    public function resetPw($data){
        //判断参数完整性
        if(!isset($data['mobile'])){
            throw new BaseException(['code'=>20001,'msg' => '手机号缺失','data'=>1]);
            return false;
        }
        if(!isset($data['code']) || !$this->checkCode($data['code'],$data['mobile'])){
            throw new BaseException(['code'=>20002,'msg' => '缺少验证码或验证码失效','data'=>1]);
            return false;
        }
        if(!isset($data['password'])||!isset($data['repassword'])){
            throw new BaseException(['code'=>20003,'msg' => '密码缺失','data'=>1]);
            return false;
        }
        if($data['password'] != $data['repassword'] ){
            throw new BaseException(['code'=>20004,'msg' => '两次密码不一致','data'=>1]);
            return false;
        }
        $user = self::get(['mobile'=>$data['mobile']]);
        if($user){
            if(!$user->allowField(true)->save(['password'=>$data['password']])){
                throw new BaseException(['code'=>20005,'msg' => '密码修改失败','data'=>1]);
                return false;
            }else{
                return true;
            }
        }else{
            throw new BaseException(['code'=>20006,'msg' => '找不到对应手机号用户','data'=>1]);
            return false;
        }
    }

    /**
     * 个人中心菜单列表
     * @return array
     */
    public function getMenus()
    {
        $menus = [
            'address' => [
                'name' => '收货地址',
                'url' => 'pages/address/index',
                'icon' => 'map'
            ],
            'coupon' => [
                'name' => '领券中心',
                'url' => 'pages/coupon/coupon',
                'icon' => 'lingquan'
            ],
            'sharing_order' => [
                'name' => '拼团订单',
                'url' => 'pages/sharing/order/index',
                'icon' => 'pintuan'
            ],
            'my_coupon' => [
                'name' => '我的优惠券',
                'url' => 'pages/user/coupon/coupon',
                'icon' => 'youhuiquan'
            ],
            'dealer' => [
                'name' => '分销中心',
                'url' => 'pages/dealer/index/index',
                'icon' => 'fenxiaozhongxin'
            ],
            'help' => [
                'name' => '我的帮助',
                'url' => 'pages/user/help/index',
                'icon' => 'help'
            ],
        ];
        // 判断分销功能是否开启
        if (DealerSettingModel::isOpen()) {
            $menus['dealer']['name'] = DealerSettingModel::getDealerTitle();
        } else {
            unset($menus['dealer']);
        }
        return $menus;
    }
}
